package com.venutech.gongan.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.shihang.misc.date.DateTimeUtil;
import com.venutech.gongan.common.Constants;
import com.venutech.gongan.dao.*;
import com.venutech.gongan.dto.rpc.common.WorkStatus;
import com.venutech.gongan.dto.rpc.common.WorkType;
import com.venutech.gongan.entity.*;
import com.venutech.gongan.service.DictDataService;
import com.venutech.gongan.service.WorkService;
import com.venutech.gongan.service.WorkSpConfigService;
import com.venutech.gongan.vo.*;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class WorkServiceImpl implements WorkService {
    @Resource
    private WorkMapper workMapper;

    @Autowired
    private JkgwMapper jkgwMapper;

    @Autowired
    private QdsxjMapper qdsxjMapper;

    @Autowired
    private WorkSpConfigService workSpConfigService;

    @Autowired
    private WorkSpHistoryMapper workSpHistoryMapper;

    @Autowired
    private SpGrantMapper spGrantMapper;

    @Autowired
    private SpGrantViewTimeSpanMapper viewTimeSpanMapper;

    @Autowired
    private DictDataService dictDataService;

    @Value("${file.path-mapping}")
    String filePathMapping;

    @Override
    public int insert(Work work) {
        return workMapper.insert(work);
    }

    @Override
    public Work getById(Integer wk_id) {
        return workMapper.getById(wk_id);
    }

    @Override
    public WorkInfoDto getWorkInfo(int workId) {
        Work work = workMapper.getById(workId);
        WorkInfoDto workInfoDto = assembleWorkInfoDto(work);
        if(work.getWk_type() == WorkType.VideoPrivilegeApplication.getValue()) {
            SpGrant spGrant = spGrantMapper.getByWorkId(work.getWk_id());
            if(Objects.nonNull(spGrant)) {
                VideoPrivilegeWorkDto videoPrivilegeWorkDto = new VideoPrivilegeWorkDto();
                videoPrivilegeWorkDto.setWorkId(spGrant.getWk_id());
                videoPrivilegeWorkDto.setStartTime(DateTimeUtil.formatDateTime(spGrant.getSp_grant_start()));
                videoPrivilegeWorkDto.setEndTime(DateTimeUtil.formatDateTime(spGrant.getSp_grant_end()));
                List<SpGrantViewTimeSpan> viewTimeSpans = viewTimeSpanMapper.getBySpGrantId(spGrant.getSp_grant_id());
                if(!CollectionUtils.isEmpty(viewTimeSpans)) {
                    List<ViewTimeSpanDto> viewTimeSpanDtos = new ArrayList<>();
                    for (SpGrantViewTimeSpan viewTimeSpan : viewTimeSpans) {
                        ViewTimeSpanDto dto = new ViewTimeSpanDto();
                        dto.setViewStartTime(DateTimeUtil.formatDateTime(viewTimeSpan.getTime_span_start()));
                        dto.setViewEndTime(DateTimeUtil.formatDateTime(viewTimeSpan.getTime_span_end()));
                        viewTimeSpanDtos.add(dto);
                    }
                    videoPrivilegeWorkDto.setViewTimeSpans(viewTimeSpanDtos);
                }
                workInfoDto.setVideoPrivilegeWork(videoPrivilegeWorkDto);
            }
        }

        return workInfoDto;
    }

    @Override
    public WorkInfoDto getPatrolWorkInfo(int workId) {
        Work work = workMapper.getById(workId);
        WorkInfoDto workInfoDto = assemblePatrolWorkInfoDto(work);
        return workInfoDto;
    }


//    @Override
//    public Page<Work> getInfo(Integer pageNo, Integer pageSize, String begintime, String endtime,
//                              Integer wk_type) {
//        Page<Work> page = new Page<>(pageNo,pageSize);
//        SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        List<Work> list = workMapper.getInfo(begintime,endtime,page,wk_type );
//        for(int i=0;i<list.size();i++){
//            Work work =list.get(i);
//            work.setStartTime(df.format(new Date(work.getWk_sq_time().getTime())));
//        }
//        return page.setRecords(list);
//    }

    @Override
    public Page<WorkInfoDto> getWorkInfoList(Integer pageNo, Integer pageSize, String begintime, String endtime, Integer wk_type, String poleName, Integer workStatus) {
        Page<WorkInfoDto> workInfoDtoPage = new Page<>(pageNo,pageSize);
        Page<Work> page = new Page<>(pageNo,pageSize);
        List<Work> works = workMapper.getInfo(begintime,endtime,workInfoDtoPage,wk_type, poleName, workStatus);
        if(CollectionUtils.isEmpty(works)) {
            return workInfoDtoPage;
        }
        List<WorkInfoDto> workInfoList = new ArrayList<>();
        works.forEach(work -> {
            WorkInfoDto dto = assembleWorkInfoDto(work);
            workInfoList.add(dto);
        });
        return workInfoDtoPage.setRecords(workInfoList);
    }

    @Override
    public Page<WorkInfoDto> getPatrolWorkInfoList(Integer pageNo, Integer pageSize, String poleName) {
        Page<WorkInfoDto> workInfoDtoPage = new Page<>(pageNo, pageSize);
        Page<Work> page = new Page<>(pageNo, pageSize);
        List<Work> works = workMapper.getPatrolWorkInfo(null, null, workInfoDtoPage,  Constants.WORK_TYPE_PATROL, poleName, null);
        if(CollectionUtils.isEmpty(works)) {
            return workInfoDtoPage;
        }
        List<WorkInfoDto> workInfoList = new ArrayList<>();
        works.forEach(work -> {
            WorkInfoDto dto = assemblePatrolWorkInfoDto(work);
            workInfoList.add(dto);
        });
        return workInfoDtoPage.setRecords(workInfoList);

    }

    @Override
    public Page<Work> getInfo2(Integer pageNo, Integer pageSize, String begintime, String endtime, Integer wk_type, Integer user_id) {
        Page<Work> page = new Page<>(pageNo,pageSize);
        List<Work> list = workMapper.getInfo2(begintime,endtime,page,wk_type,user_id);
        return page.setRecords(list);
    }

    @Override
    public Page<Work> getInfo3(Integer pageNo, Integer pageSize, String begintime, String endtime, Integer wk_type, Integer user_id) {
        Page<Work> page = new Page<>(pageNo,pageSize);
        List<Work> list = workMapper.getInfo3(begintime,endtime,page,wk_type,user_id);
        SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        list.forEach(e->{
            e.setStartTime(df.format(new Date(e.getWk_sq_time().getTime())));
        });
        return page.setRecords(list);
    }

    @Override
    public List<Work> getAllWorks(Integer userId,Integer wk_type) {
        return workMapper.getAllWorks(userId,wk_type);
    }

    @Override
    public Integer getSelCountByDay() {
        return workMapper.getSelCountByDay();
    }

    @Override
    public Integer getTotalCount() {
        return workMapper.getTotalCount();
    }

    @Override
    public Integer getSelCountByUser(Integer user_id) {
        return workMapper.getSelCountByUser(user_id);
    }

    @Override
    public Integer getTotalCountByUser(Integer user_id) {
        return workMapper.getTotalCountByUser(user_id);
    }

    @Override
    public List<Work> getSelByWeek(Integer user_id) {
        return workMapper.getSelByWeek(user_id);
    }

    @Override
    public Integer getSelCountByWeek(Integer user_id) {
        return workMapper.getSelCountByWeek(user_id);
    }

    @Override
    public List<Work> getSelByMonth(Integer user_id) {
        return workMapper.getSelByMonth(user_id);
    }

    @Override
    public Integer getSelCountByMonth(Integer user_id) {
        return workMapper.getSelCountByMonth(user_id);
    }


    //API
    @Transactional
    @Override
    public int insertWorkDto(WorkDto workDto) {
        int num = workMapper.insertWorkDto(workDto);
//        if(workDto.getType() == WorkType.VideoPrivilegeApplication.getValue()) {
//            WorkSpConfig workSpConfig = workSpConfigService.getFirstSpUser(workDto.getType());
//            if(Objects.nonNull(workSpConfig)) {
//                int spUserId = workSpConfig.getUser_id();    // 视频权限审批人
//                updateSpUser(workDto.getWk_id(), spUserId);
//                SpGrant spGrant = new SpGrant();
//                spGrant.setSp_grant_gw_id(workDto.getPoleId());
//                spGrant.setSp_grant_sb_id(workDto.getEquipmentId());
//                spGrant.setWk_id(workDto.getWk_id());
//                spGrant.setSp_grant_sq_user_id(workDto.getUserId());
//                spGrantMapper.insert(spGrant);
//            }
//        }

        return num;
    }

    @Transactional
    @Override
    public int createVideoPrivilegeWork(SpGrantDto spGrantDto){
        Work work = new Work();
        work.setWk_type(WorkType.VideoPrivilegeApplication.getValue());
        work.setWk_sq_user_id(spGrantDto.getUserId());
        work.setWk_content(spGrantDto.getContent());
        work.setWk_state(WorkStatus.InProgress.getValue());
        work.setWk_area_code(spGrantDto.getAreaCode());
        workMapper.insert(work);

        SpGrant spGrant = new SpGrant();
        spGrant.setWk_id(work.getWk_id());
        spGrant.setSp_grant_sq_user_id(spGrantDto.getUserId());

        spGrant.setSp_grant_start(new Date(spGrantDto.getStartTime()));
        spGrant.setSp_grant_end(new Date(spGrantDto.getEndTime()));

        int num = spGrantMapper.insert(spGrant);

        if(!CollectionUtils.isEmpty(spGrantDto.getViewTimeSpans())) {
            spGrantDto.getViewTimeSpans().forEach(ts -> {
                SpGrantViewTimeSpan viewTimeSpan = new SpGrantViewTimeSpan();
                viewTimeSpan.setSp_grant_id(spGrant.getSp_grant_id());
                viewTimeSpan.setTime_span_start(new Date(ts.getStartTime()));
                viewTimeSpan.setTime_span_end(new Date(ts.getEndTime()));
                viewTimeSpanMapper.insert(viewTimeSpan);
            });
        }

        return num;
    }

    @Override
    public int insertWorkExtDto(WorkExtDto workExtDto) {
        return workMapper.insertWorkExtDto(workExtDto);
    }

    @Override
    public List<Work> getWorkDtoList(Integer userId,Integer workType, String startTime, String endTime) {
        return workMapper.getWorkDtoList(userId,workType,startTime,endTime);
    }

    @Override
    public List<Work> getWorkDtoList(Integer userId,Integer workType, Integer pageNo, Integer pageSize) {
        Page<Work> page = new Page<>(pageNo,pageSize);
        return workMapper.getWorkDtoListByPage(userId,workType, page);
    }

    @Override
    public int poleWorkDto(WorkDto work) {
        return workMapper.poleWorkDto(work);
    }

    @Override
    public int getCountByTypeAndDay(int workType, Date startDay) {
        return workMapper.getCountByTypeAndDay(workType, startDay);
    }

    @Override
    public int getCountByType(int workType) {
        return workMapper.getCountByType(workType);
    }

    @Override
    public List<Work> getByTypeAndDateRange(int workType, Date startDate, Date endDate) {
        return workMapper.getByTypeAndDateRegion(workType, startDate, endDate);
    }

    @Override
    public int getSelectUnBindCount() {
        return workMapper.getSelectUnBindCount();
    }

    @Override
    public int insertOperation(Operation v) {
        return workMapper.insertOperation(v);
    }

    @Override
    public Page<Operation> selectOperationList(Integer pageNo, Integer pageSize, Integer work_device_type) {
        Page<Operation> page = new Page<>(pageNo,pageSize);
        List<Operation> list=  workMapper.selectOperationList(page,work_device_type);
        return page.setRecords(list);
    }

    @Override
    public Operation getOperationById(Operation v) {
        return workMapper.getOperationById(v);
    }

    @Override
    public List<Work> getWorkByUserid(Integer userId, String sTime, String eTime) {
        return workMapper.getWorkByUserid(userId,sTime,eTime);
    }

    @Override
    public void approveWork(int workId, int spUserId) {
        workMapper.approveWork(workId, spUserId);
    }

    /**
     * 批准视频申请杆工单
     * @param workId
     * @param spUserId
     */
    @Transactional
    @Override
    public void approveVideoPrivilegeWork(int workId, int spUserId) {
        /*
        Work work = getById(workId);
        List<WorkSpConfig> workSpConfigs = workSpConfigService.getByWorkType(work.getWk_type());
        if(CollectionUtils.isEmpty(workSpConfigs)) {
            return;
        }

        int maxFormerSeq = 0;
        int workState = 0;  //  最终审批状态
        List<WorkSpHistory> spHistories = workSpHistoryMapper.findByWorkId(workId);
        if(CollectionUtils.isEmpty(spHistories)) {
            maxFormerSeq = 0;
            if(workSpConfigs.size() > 1) {
                workState = Constants.WORK_STATE_IN_PROGRESS;
            } else {
                workState = Constants.WORK_STATE_APPROVED;
            }
        } else {
            maxFormerSeq  = spHistories.get(spHistories.size() - 1).getWk_sequence();
            if(maxFormerSeq + 1 >= workSpConfigs.size()) {
                workState = Constants.WORK_STATE_APPROVED;
            } else {
                workState = Constants.WORK_STATE_IN_PROGRESS;
            }
        }

        int currentSeq = maxFormerSeq + 1;
        int nextSeq  =  currentSeq + 1;
        if(currentSeq > workSpConfigs.size()) {
            currentSeq = workSpConfigs.size();
        }
        if(nextSeq > workSpConfigs.size()) {
            nextSeq = workSpConfigs.size();
        }

        final int currentSequence = currentSeq;
        final int nextSequence = nextSeq ;
        Optional<WorkSpConfig> currentSpConfig = workSpConfigs.stream().filter(spConfig -> spConfig.getWk_sequence() == currentSequence).findFirst();
        Optional<WorkSpConfig> nextSpConfig  =  workSpConfigs.stream().filter(spConfig -> spConfig.getWk_sequence() == nextSequence).findFirst();

        workMapper.approveVideoSpWork(workState, nextSpConfig.get().getUser_id(), workId);
        WorkSpHistory spHistory = new WorkSpHistory();
        spHistory.setSp_user_id(spUserId);
        spHistory.setWk_id(workId);
        spHistory.setWk_sequence(currentSpConfig.get().getWk_sequence());
        spHistory.setWk_sp_result(Constants.WORK_STATE_APPROVED);
        workSpHistoryMapper.insert(spHistory);
         */

        workMapper.approveVideoSpWork(WorkStatus.Approved.getValue(), spUserId, workId);
    }

    /**
     * 驳回视频申请工单
     * @param workId
     * @param spUserId
     */
    @Transactional
    @Override
    public void declineVideoPrivilegeWork(int workId, int spUserId) {
        /*
        Work work = getById(workId);
        List<WorkSpConfig> workSpConfigs = workSpConfigService.getByWorkType(work.getWk_type());
        if(CollectionUtils.isEmpty(workSpConfigs)) {
            return;
        }

        Optional<WorkSpConfig> spConfig = workSpConfigs.stream().filter(spcfg -> spcfg.getUser_id() == spUserId).findFirst();
        workMapper.declineVideoSpWork(spUserId, workId);
        WorkSpHistory spHistory = new WorkSpHistory();
        spHistory.setSp_user_id(spUserId);
        spHistory.setWk_id(workId);
        spHistory.setWk_sequence(spConfig.get().getWk_sequence());
        spHistory.setWk_sp_result(Constants.WORK_STATE_REJECTED);
        workSpHistoryMapper.insert(spHistory);
        */

        workMapper.declineVideoSpWork(spUserId, workId);
    }

    @Override
    public int updateSpUser(int workId, int spUserId) {
        return workMapper.updateSpUser(workId, spUserId);
    }

    @Override
    public WorkInfoDto assembleWorkInfoDto(Work work) {
        WorkInfoDto dto = new WorkInfoDto();
        dto.setWorkId(work.getWk_id());
        dto.setWorkTypeName(WorkType.getNameByValue(work.getWk_type()));
        dto.setWorkType(work.getWk_type());
        dto.setApplier(work.getSqname());
        dto.setWorkContent(work.getWk_content());
        Jkgw pole = jkgwMapper.getById(work.getWk_gw_id());
        if(Objects.nonNull(pole)) {
            dto.setPoleName(pole.getGw_name());
        }
        Qdsxj equip = qdsxjMapper.getById(work.getWk_sb_id());
        if(Objects.nonNull(equip)) {
            dto.setEquipName(equip.getSb_name());
        }
        dto.setApplyTime(DateTimeUtil.formatDateTime(work.getWk_sq_time()));
        if(work.getWk_state() == WorkStatus.InProgress.getValue()) {
            if(work.getWk_type() == WorkType.VideoPrivilegeApplication.getValue()) {
                dto.setWorkStatus("审批中");
            } else{
                dto.setWorkStatus("处理中");
            }
        } else if(work.getWk_state() == WorkStatus.Approved.getValue()) {
            if(work.getWk_type() == WorkType.VideoPrivilegeApplication.getValue()) {
                dto.setWorkStatus("已批准");
            } else{
                dto.setWorkStatus("已处理");
            }
        } else if(work.getWk_state() == WorkStatus.Rejected.getValue()) {
            if(work.getWk_type() == WorkType.VideoPrivilegeApplication.getValue()) {
                dto.setWorkStatus("已驳回");
            }
        }
        dto.setApprover(work.getSpname());

        String filePath1 = String.format("%s%s", filePathMapping, work.getWk_ppciture_1());
        String filePath2 = String.format("%s%s", filePathMapping, work.getWk_ppciture_2());
        String filePath3 = String.format("%s%s", filePathMapping, work.getWk_ppciture_3());

        if(Strings.isNotBlank(work.getWk_ppciture_1())) {
            dto.setPic1(filePath1);
        }
        if(Strings.isNotBlank(work.getWk_ppciture_2())) {
            dto.setPic2(filePath2);
        }
        if(Strings.isNotBlank(work.getWk_ppciture_3())) {
            dto.setPic3(filePath3);
        }
        dto.setAreaCode(work.getWk_area_code());
        List<DictData> mjAreaList = dictDataService.getSelAllMjxzqy();
        Optional dictDataOpt = mjAreaList.stream().filter(dictData -> dictData.getDict_value().equals(work.getWk_area_code())).findFirst();
        if(dictDataOpt.isPresent()) {
            dto.setAreaName(((DictData)dictDataOpt.get()).getDict_label());
        }


        return dto;
    }

    @Override
    public int updateWork(Integer workId, int user_id) {
        return workMapper.updateWork(workId,user_id);
    }

    private WorkInfoDto assemblePatrolWorkInfoDto(Work work) {
        WorkInfoDto dto = new WorkInfoDto();
        dto.setWorkId(work.getWk_id());
        dto.setWorkTypeName(WorkType.getNameByValue(work.getWk_type()));
        dto.setApplier(work.getSqname());
        dto.setWorkContent("巡检打卡");
        Jkgw pole = jkgwMapper.getById(work.getWk_gw_id());
        if(Objects.nonNull(pole)) {
            dto.setPoleName(pole.getGw_name());
        }
        dto.setApplyTime(DateTimeUtil.formatDateTime(work.getWk_sq_time()));
        dto.setApprover(work.getSpname());
        return dto;
    }



}
